using System.Collections.Generic;
using System.Diagnostics;
using UnityEngine.Events;

public class RedPointMgr : Singleton<RedPointMgr>
{
    
    /// <summary>
    /// 所有红点树的根节点集合
    /// </summary>
    private readonly Dictionary<string, RedPointNote> allRedTree = new Dictionary<string, RedPointNote>();
    
    /// <summary>
    /// 添加结点
    /// </summary>
    /// <param name="notePath">节点的路径, 例如: "商城|装备|10级装备|武器" </param>
    public RedPointNote AddNote(string notePath, int redPoint = 0)
    {
        // 判断字符串是否合法
        if (string.IsNullOrEmpty(notePath)) return null;
        
        // 分割字符串
        var noteNames = notePath.Split('|');

        // 查找根节点, 如果没有就创建一个新的
        var noteRootName = noteNames[0];
        if (!allRedTree.TryGetValue(noteRootName, out var noteRoot))
        {
            noteRoot = CreateNote(noteRootName, null);
            allRedTree.Add(noteRoot.name, noteRoot);
        }
        
        // 创建子结点
        for (int i = 1 ; i < noteNames.Length; i++)
        {
            var childName = noteNames[i];
            if (!noteRoot.allChildNote.TryGetValue(childName, out var childNote))
            {
                childNote = CreateNote(childName, noteRoot);
            }
            noteRoot = childNote;
        }

        // ColorLog.LogOrange($"[{noteRoot.name}]节点添加完成!");

        if (redPoint > 0)
        {
            // 修改红点数量, 刷新结点
            noteRoot.redCount = redPoint;
            RefreshParentNote(noteRoot);
        }
        ColorLog.LogOrange($"name:{noteRoot.name}红点数量:{noteRoot.RedCount}");
       
        
        return noteRoot;
    }

    /// <summary>
    /// 获取节点
    /// </summary>
    /// <param name="notePath">节点的路径</param>
    /// <returns></returns>
    public RedPointNote GetNote(string notePath)
    {
        // 判断字符串是否符合规范
        if (string.IsNullOrEmpty(notePath)) return null;

        // 分割字符串
        var noteNames = notePath.Split('|');
        
        // 寻找根节点
        if (!allRedTree.TryGetValue(noteNames[0], out var noteRoot)) return null;

        // 查找子结点
        for (int i = 1; i < noteNames.Length; i++)
        {
            if (!noteRoot.allChildNote.TryGetValue( noteNames[i], out var childNote)) return null;
            noteRoot = childNote;
        }

        // 返回查找到的结点
        return noteRoot;
    }

    /// <summary>
    ///  修改结点
    /// </summary>
    /// <param name="notePath">节点路径</param>
    /// <param name="redCount">红点数量</param>
    public void ChangeNote(string notePath, int redCount)
    {
        // 获取节点
        var getNote = GetNote(notePath);
        
        //判断节点是否为空 ,修改的数值是否跟原来不一致
        if (getNote != null && getNote.redCount != redCount)
        {
            // 修改自身红点数量
            getNote.ChangeRedCount(redCount);
            
            // 刷新父级节点
            RefreshParentNote(getNote);
        }
    }
    
    /// <summary>
    /// 删除结点 
    /// </summary>
    /// <param name="notePath">节点路径</param>
    public void RemoveNote(string notePath)
    {
        // 获取结点
        var getNote = GetNote(notePath);
        
        // 判断是否为空
        if (getNote == null) return;

        if (getNote.parentNote != null)
        {
            getNote.parentNote.RemoteNote(getNote.name);
            getNote.ChangeRedCount(0);
            RefreshParentNote(getNote);
        }
        else
        {
            // 只有根节点没有父级结点, 所以从树的集合中删除
            allRedTree.Remove(getNote.name);
        }
    }
    
    private RedPointNote CreateNote(string noteName, RedPointNote parentNote)
    {
        // 创建结点
        var newNote = new RedPointNote(noteName, parentNote);

        // 给父级结点添加子结点
        parentNote?.allChildNote.Add(noteName, newNote);
        
        // ColorLog.LogOrange($"创建了新的结点:{noteName}");
        
        return newNote;
    }

    /// <summary>
    /// 循环网上去刷新父级结点
    /// </summary>
    /// <param name="note"></param>
    private void RefreshParentNote( RedPointNote note )
    {
        var refreshNote = note.parentNote;
        while (refreshNote != null)
        {
            refreshNote.RefreshRedPoint();
            refreshNote = refreshNote.parentNote;
        }
    }

    /// <summary>
    /// 添加回调函数的方法
    /// </summary>
    /// <param name="notePath">节点路径</param>
    /// <param name="callback">回调函数</param>
    public void AddCallback(string notePath, UnityAction<RedPointNote> callback )
    {
        var getNote = GetNote(notePath);
        
        if (getNote == null) return;
        
        getNote.callback = callback;
        getNote.InvokeCallback();
    }
}
    